﻿using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Net.Sockets;
using System.Text;
using Newtonsoft.Json;

namespace TCP232.PublicMethod
{
    public static class ExtensionMethod
    {
        public static int ToInt32(this IEnumerable<byte> bytes, int startIndex)
        {
            return Convert.ToInt32(BitConverter.ToString(bytes.ToArray(), startIndex, 2).Replace("-", ""), 16) - 32768;
        }

        public static byte[] GetCRC16(this byte[] data)
        {
            //crc计算赋初始值
            int crc = 0xffff;
            for (int i = 0; i < data.Length; i++)
            {
                crc = crc ^ data[i];
                for (int j = 0; j < 8; j++)
                {
                    int temp;
                    temp = crc & 1;
                    crc = crc >> 1;
                    crc = crc & 0x7fff;
                    if (temp == 1)
                    {
                        crc = crc ^ 0xa001;
                    }
                    crc = crc & 0xffff;
                }
            }
            //CRC寄存器的高低位进行互换
            byte[] crc16 = new byte[2];
            //CRC寄存器的低8位变成高8位
            crc16[0] = (byte)(crc & 0xff);
            //CRC寄存器的高8位变成低8位，
            crc16[1] = (byte)((crc >> 8) & 0xff);
            return crc16;
        }

        public static void DisConnect(this Socket socket)
        {
            if (socket.IsConnected())
            {
                socket.Shutdown(SocketShutdown.Both);
            }
            socket.Dispose();
        }

        public static bool IsConnected(this Socket socket)
        {
            return socket?.Connected ?? false;
        }

        public static int Write(this Socket socket, byte[] data, Action action)
        {
            if (socket.IsConnected())
            {
                return socket.Send(data);
            }
            action();
            return 0;
        }

        public static string ToHexString(this byte[] bytes)
        {
            StringBuilder stringBuilder = new StringBuilder();
            if (bytes?.Length > 0)
            {
                for (int i = 0; i < bytes.Length - 1; i++)
                {
                    stringBuilder.Append(bytes[i].ToString("X2") + " ");
                }

                stringBuilder.Append(bytes[^1].ToString("X2"));
            }

            return stringBuilder.ToString();
        }

        public static byte[] ToBytes(this string hexString)
        {
            //hexString = "3  123456 2";
            //以' '分割字符串，并去掉空字符
            string[] strings = hexString.Split(' ', StringSplitOptions.RemoveEmptyEntries);
            List<byte> result = new List<byte>();
            for (int i = 0; i < strings.Length; i++) //逐个字符变为16进制字节数据 
            {
                if (strings[i].Length > 2)
                {
                    while (strings[i].Length > 2)
                    {
                        var item = strings[i][..2];
                        strings[i] = strings[i].Remove(0, 2);
                        result.Add(Convert.ToByte(item, 16));
                    }

                    if (strings[i].Length > 0)
                    {
                        result.Add(Convert.ToByte(strings[i], 16));
                    }
                }
                else
                {
                    result.Add(Convert.ToByte(strings[i], 16));
                }
            }

            return result.ToArray();
        }

        public static void SaveAsJsonToFile<T>(this T t, string filePath)
        {
            //if (!File.Exists(filePath))
            //{
            //    using (File.Create(filePath)) { };
            //}

            var jsonData = JsonConvert.SerializeObject(t, new JsonSerializerSettings()
            {
                Formatting = Formatting.Indented,
                TypeNameHandling = TypeNameHandling.Auto
            });

            using StreamWriter file = new StreamWriter(filePath, false);
            file.Write(jsonData);
            file.Flush();
            //File.WriteAllText(filePath, jsonData);
        }
    }
}